<template>
  <div>
    <el-collapse
      v-if="volumes && volumes.length > 0"
      v-model="uiState.activeName"
    >
      <el-collapse-item
        v-for="(item, index) in volumes"
        :key="index"
        :title="`${item.name} ( ${getVolumeType(item)} )`"
        :name="index"
      >
        <template #title>
          <div class="flex w-full justify-between items-center pr-5">
            <span>{{ `${item.name} ( ${getVolumeType(item)} )` }}</span>
            <confirm-button
              type="danger"
              icon="Delete"
              link
              delete-mention
              @confirm="onDeleteVolume(index)"
            />
          </div>
        </template>
        <el-form label-position="top" :disabled="readonly">
          <el-row>
            <el-col :span="24">
              <el-form-item
                :label="$t('business.workload.volume_name')"
                required
              >
                <ko-data-item
                  v-model:model-value="item.name"
                  class="w-full"
                  itemType="input"
                />
              </el-form-item>
            </el-col>
          </el-row>
          <el-form-item
            v-if="isVolumeHasDefaultModel(item)"
            :label="$t('business.workload.default_mode')"
          >
            <ko-data-item
              v-model:model-value="getVolumeSource(item).defaultMode"
              itemType="number"
              placeholder="644"
            />
          </el-form-item>
          <el-form-item
            v-if="isVolumeHasResource(item)"
            :label="getVolumeType(item)"
          >
            <ko-data-item
              v-if="item.configMap"
              v-model:model-value="item.configMap.name"
              item-ype="select"
              :selections="configMapList"
              :val-prop="{
                key: 'metadata.name',
                label: 'metadata.name',
                value: 'metadata.name'
              }"
            />
            <ko-data-item
              v-if="item.secret"
              v-model:model-value="item.secret.secretName"
              item-ype="select"
              :val-prop="{
                key: 'metadata.name',
                value: 'metadata.name',
                label: 'metadata.name'
              }"
              :selections="secretList"
            />
            <ko-data-item
              v-if="item.persistentVolumeClaim"
              v-model:model-value="item.persistentVolumeClaim.claimName"
              item-ype="select"
              :selections="pvcList"
              :val-prop="{
                key: 'metadata.name',
                value: 'metadata.name',
                label: 'metadata.name'
              }"
            />
          </el-form-item>
          <table
            v-if="isVolumeHasKV(item)"
            style="width: 98%"
            class="tab-table"
          >
            <tr>
              <th scope="col" width="43%" align="left">
                <label>{{ $t("business.workload.key") }}</label>
              </th>
              <th scope="col" width="43%" align="left">
                <label>{{ $t("business.workload.path") }}</label>
              </th>
              <th align="left" />
            </tr>
            <tr v-for="(row, index) in getVolumeItems(item)" v-bind:key="index">
              <td>
                <ko-data-item
                  v-model:model-value="row.key"
                  item-ype="flatSelect"
                  :selections="getVolumeItemOptions(item)"
                />
              </td>
              <td>
                <ko-data-item v-model:model-value="row.path" itemType="input" />
              </td>
              <td>
                <el-button
                  type="text"
                  style="font-size: 10px"
                  @click="onDeleteVolumeItem(item, index)"
                >
                  {{ $t("commons.button.delete") }}
                </el-button>
              </td>
            </tr>
            <tr>
              <td align="left">
                <el-button
                  :disabled="!isVolumeHasNotEmptyResource(item)"
                  @click="onAddVolumeItem(item)"
                >
                  {{ $t("commons.button.add") }}
                </el-button>
              </td>
            </tr>
          </table>
          <el-form-item v-if="isVolumeHasOptional(item)" label="Optional">
            <ko-data-item
              v-if="item.configMap"
              v-model:model-value="item.configMap.optional"
              itemType="radio"
              :radios="uiState.optional_list"
            />
            <ko-data-item
              v-else-if="item.secret"
              v-model:model-value="item.secret.optional"
              itemType="radio"
              :radios="uiState.optional_list"
            />
          </el-form-item>
          <div v-if="item.nfs">
            <el-form-item label="Path">
              <ko-data-item
                v-model:model-value="item.nfs.path"
                itemType="input"
              />
            </el-form-item>
            <el-form-item label="Server">
              <ko-data-item
                v-model:model-value="item.nfs.server"
                itemType="input"
              />
            </el-form-item>
          </div>
          <div v-if="item.hostPath">
            <el-form-item :label="$t('business.storage.path_or_node')" required>
              <ko-data-item
                v-model:model-value="item.hostPath.path"
                itemType="input"
              />
            </el-form-item>
            <el-form-item :label="$t('business.workload.type')">
              <ko-data-item
                v-model:model-value="item.hostPath.type"
                item-ype="flatSelect"
                :selections="uiState.host_path_list"
              />
            </el-form-item>
          </div>
        </el-form>
      </el-collapse-item>
    </el-collapse>
    <el-row style="margin-top: 10px">
      <el-col :span="12">
        <el-dropdown
          placement="bottom"
          trigger="click"
          @command="onAddVolumeItemFromType"
        >
          <el-button class="search-btn">
            {{ $t("business.workload.add") }}
            <i class="el-icon-arrow-down el-icon--right" />
          </el-button>
          <template v-slot:dropdown>
            <el-dropdown-menu>
              <el-dropdown-item
                v-for="(item, index) in uiState.volume_type_list"
                :key="index"
                :command="item.value"
              >
                {{ item.label }}
              </el-dropdown-item>
            </el-dropdown-menu>
          </template>
        </el-dropdown>
      </el-col>
    </el-row>
  </div>
</template>

<script setup lang="ts">
import KoDataItem from "@/views/domain/kubeHud/views/components/ko-data-item/index.vue";
import {
  ConfigMap,
  KeyToPath,
  PersistentVolumeClaim,
  Secret,
  Volume
} from "../../../api/k8s";
import ConfirmButton from "@/views/domain/kubeHud/views/components/ConfirmButton/index.vue";
import { reactive } from "vue";
import { useI18n } from "vue-i18n";
import { VolumeSimpleType } from "./types";

const { t } = useI18n();

type Prop = {
  configMapList?: ConfigMap[];
  pvcList?: PersistentVolumeClaim[];
  secretList?: Secret[];
  readonly?: boolean;
};

const props = defineProps<Prop>();
const volumes = defineModel<Volume[]>("volumes", { default: [] });

const uiState = reactive({
  activeName: 0,
  volume_type_list: [
    { label: "NFS", value: "NFS" },
    { label: "PVC", value: "PVC" },
    { label: "EmptyDir", value: "EmptyDir" },
    { label: "HostPath", value: "HostPath" },
    { label: "ConfigMap", value: "ConfigMap" },
    { label: "Secret", value: "Secret" }
  ],
  optional_list: [
    { label: t("business.workload.yes"), value: true },
    { label: t("business.workload.no"), value: false }
  ],
  host_path_list: [
    "DirectoryOrCreate",
    "Directory",
    "FileOrCreate",
    "File",
    "Socket",
    "CharDevice",
    "BlockDevice"
  ]
});

const getVolumeType = (item: Volume) => {
  if (item.configMap) return "ConfigMap";
  else if (item.secret) return "Secret";
  else if (item.persistentVolumeClaim) return "PVC";
  else if (item.emptyDir) return "EmptyDir";
  else if (item.hostPath) return "HostPath";
  else if (item.nfs) return "NFS";
  else return "";
};

const getVolumeSource = (item: Volume): any => {
  switch (getVolumeType(item)) {
    case "ConfigMap":
      return item.configMap;
    case "Secret":
      return item.secret;
    case "PVC":
      return item.persistentVolumeClaim;
    case "EmptyDir":
      return item.emptyDir;
    case "HostPath":
      return item.hostPath;
    case "NFS":
      return item.nfs;
    default:
      return {};
  }
};

// 获取卷绑定key列表
const getVolumeItems = (item: Volume): KeyToPath[] | undefined => {
  if (item.configMap) return item.configMap.items;
  else if (item.secret) return item.secret.items;
};

const onDeleteVolumeItem = (item: Volume, index: number) => {
  if (item.configMap) {
    item.configMap.items?.splice(index, 1);
  } else if (item.secret) {
    item.secret.items?.splice(index, 1);
  }
};

const onAddVolumeItemFromType = (type: VolumeSimpleType) => {
  switch (type) {
    case "NFS":
      volumes.value.push({
        name: "",
        nfs: {
          path: "",
          server: ""
        }
      });
      break;
    case "PVC":
      volumes.value.push({
        name: "",
        persistentVolumeClaim: {
          claimName: ""
        }
      });
      break;
    case "EmptyDir":
      volumes.value.push({
        name: "",
        emptyDir: {}
      });
      break;
    case "HostPath":
      volumes.value.push({
        name: "",
        hostPath: {
          path: "",
          type: ""
        }
      });
      break;
    case "ConfigMap":
      volumes.value.push({
        name: "",
        configMap: {
          name: "",
          optional: false,
          items: []
        }
      });
      break;
    case "Secret":
      volumes.value.push({
        name: "",
        secret: {
          secretName: "",
          optional: false,
          items: []
        }
      });
      break;
  }

  console.log("add volume from type: ", type, volumes.value);
  uiState.activeName = volumes.value.length - 1;
};
const onAddVolumeItem = (item: Volume) => {
  console.log("add volume: ", item);
  if (item.configMap) {
    if (!item.configMap.items) item.configMap.items = [];
    item.configMap.items.push({
      key: "",
      path: ""
    });
    if (item.configMap.items.findIndex(kp => kp.key === "") > -1) {
      // 存在空key,将空key排序到前面
      item.configMap.items.sort((a, b) => {
        if (a.key === "") return -1;
        else if (b.key === "") return 1;
        else return 0;
      });
      return;
    } else {
      item.configMap.items.push({
        key: "",
        path: ""
      });
    }
  } else if (item.secret) {
    if (!item.secret.items) item.secret.items = [];
    if (item.secret.items.findIndex(kp => kp.key === "") > -1) {
      // 存在空key,将空key排序到前面
      item.secret.items.sort((a, b) => {
        if (a.key === "") return -1;
        else if (b.key === "") return 1;
        else return 0;
      });
      return;
    } else {
      item.secret.items.push({
        key: "",
        path: ""
      });
    }
  }
};

const getVolumeOptional = (item: Volume) => {
  if (item.configMap) return item.configMap.optional;
  else if (item.secret) return item.secret.optional;
  else return false;
};

const getVolumeItemOptions = (item: Volume): string[] => {
  if (item.configMap) {
    const refName = item.configMap.name;
    const targetCM = props.configMapList?.find(
      item => item.metadata.name === refName
    );
    if (!targetCM) return [];
    return targetCM.data ? Object.keys(targetCM.data) : [];
  } else if (item.secret) {
    const refName = item.secret.secretName;
    const targetSecret = props.secretList?.find(
      item => item.metadata.name === refName
    );
    if (!targetSecret) return [];
    return targetSecret.data ? Object.keys(targetSecret.data) : [];
  }
  return [];
};

const isVolumeHasDefaultModel = (item: Volume) => {
  return item.configMap || item.secret;
};

const isVolumeHasKV = (item: Volume) => {
  return item.configMap || item.secret;
};

const isVolumeHasOptional = (item: Volume) => {
  return item.configMap || item.secret;
};

const isVolumeHasResource = (item: Volume) => {
  return item.configMap || item.secret || item.persistentVolumeClaim;
};

const isVolumeHasNotEmptyResource = (item: Volume) => {
  if (item.configMap && item.configMap.name) {
    return true;
  } else if (item.secret && item.secret.secretName) {
    return true;
  }
  return false;
};

const isVolumeEnabled = (item: Volume) => {
  return (
    item.configMap ||
    item.secret ||
    item.persistentVolumeClaim ||
    item.emptyDir ||
    item.hostPath ||
    item.nfs
  );
};

const onDeleteVolume = (index: number) => {
  volumes.value.splice(index, 1);
};
</script>
